Skip to content

[Unpackaged] Fix taskbar glomming due to AUMID#20064

Merged
DHowett merged 5 commits into
mainfrom
dev/cazamor/bugfix/aumid
May 1, 2026
Merged

[Unpackaged] Fix taskbar glomming due to AUMID#20064
DHowett merged 5 commits into
mainfrom
dev/cazamor/bugfix/aumid

Conversation

@carlos-zamora
Copy link
Copy Markdown
Member

Summary of the Pull Request

The bug was caused by an AUMID mismatch between the Taskbar's .lnk file and Windows Terminal. Since no AUMID was associated with the .exe, the OS automatically creates one for us. However, #20018 added an AUMID for unpackaged scenarios, so now there was a mismatch, resulting in a new taskbar entry being created.

To fix this, we check if a .lnk points to our .exe in the taskbar. There's 3 cases here:

  1. no .lnk of interest exists --> set the AUMID normally
  2. the .lnk carries our AUMID --> set the AUMID normally
  3. the .lnk doesn't have an AUMID (aka uses the auto-resolved one) -->
    • for this launch: don't set the AUMID so that we both use the auto-resolved one
    • on next launch: set the AUMID on the .lnk and process so that they all agree

Validation Steps Performed

In unpackaged folder, move WindowsTerminal.exe to the taskbar (creates .lnk)...
✅ Double-click the .exe --> Same taskbar entry is used
✅ Double-click the .exe again --> second window goes to same taskbar entry

The first window doesn't have to close for this to work. It just * works *!

Bug introduced in #20018
Closes #20053

@carlos-zamora carlos-zamora requested a review from DHowett April 3, 2026 22:06
Comment thread src/cascadia/WindowsTerminal/WindowEmperor.cpp Fixed
@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Member

@lhecker lhecker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat code! One minor bug only.

Comment on lines +318 to +323
// GH#20053: The shell resolves taskbar grouping identity as: per-window AUMID >
// per-process AUMID > auto-derived from exe path. Before we started setting a
// process AUMID, both the pinned .lnk and the process used auto-derived
// identity, so they matched. Now that we set an explicit AUMID, a pinned .lnk
// that predates the AUMID change has no AUMID and still uses auto-derived
// identity, causing a mismatch and a duplicate taskbar button.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So LNK files essentially... cache? the AUMID that an app sets? Is that right?
So if my app ever changes the ID all LNKs are invalid?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! The LNK can either have an AUMID explicitly set or it's derived by the OS. I've definitely had a few apps update and not glom to the same taskbar entry and I'm guessing it's because they set a new AUMID.

Comment on lines +328 to +330
// AUMID for THIS launch (both sides use auto-derived identity, so they match)
// and defer stamping the shortcut to process exit. On the next launch, the pin
// has our AUMID, so we set the process AUMID to match, and both agree.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not update the LNK immediately?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See

// The pin exists but doesn't have our AUMID yet. Don't set the process
// AUMID or stamp the shortcut now. Writing the shortcut causes the
// shell to re-read it immediately, changing the pin's cached identity
// mid-launch and creating a mismatch in the opposite direction. Instead,
// stamp it at shutdown when the taskbar association no longer matters.

If we stamp now, we get two choices:

  • set process AUMID this launch: process stays auto-derived (old AUMID) + pin's identity switches to new AUMID = mismatch
  • set process AUMID: while the window is being created, the shell is auto-deriving the AUMID with the LNK. Since the two operations aren't atomic, we get a mismatch.

Deferring means that we always have a match:

  1. first launch:
    • LNK AUMID: auto-derived
    • Process AUMID: auto-derived
  2. at shutdown:
    • LNK AUMID: stamped with new AUMID
    • Process AUMID: N/A (we've shut down)
  3. next launch:
    • LNK AUMID: new AUMID
    • Process AUMID: new AUMID

These were battle scars I earned while testing/implementing this change haha.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this explanation more than the one in the code to be honest. 🙈 May be worth adjusting the comment IMO.

Comment thread src/cascadia/WindowsTerminal/WindowEmperor.cpp Outdated
Comment thread src/cascadia/WindowsTerminal/WindowEmperor.cpp Outdated
@microsoft-github-policy-service microsoft-github-policy-service Bot added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Apr 21, 2026
@microsoft-github-policy-service microsoft-github-policy-service Bot added the No-Recent-Activity This issue/PR is going stale and may be auto-closed without further activity. label Apr 29, 2026
@microsoft-github-policy-service
Copy link
Copy Markdown
Contributor

This pull request has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 7 days. It will be closed if no further activity occurs within 7 days of this comment.

@carlos-zamora carlos-zamora removed Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something No-Recent-Activity This issue/PR is going stale and may be auto-closed without further activity. labels Apr 29, 2026
@github-actions

This comment has been minimized.

Comment thread src/cascadia/WindowsTerminal/WindowEmperor.cpp Fixed
Comment thread src/cascadia/WindowsTerminal/WindowEmperor.cpp Fixed
Comment thread src/cascadia/WindowsTerminal/WindowEmperor.cpp Fixed
Comment thread src/cascadia/WindowsTerminal/WindowEmperor.cpp Fixed
Comment thread src/cascadia/WindowsTerminal/WindowEmperor.cpp Fixed
Comment thread src/cascadia/WindowsTerminal/WindowEmperor.cpp Fixed
Comment thread src/cascadia/WindowsTerminal/WindowEmperor.cpp Fixed
Copy link
Copy Markdown
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so i have a potential third case for you

well, fourth

  1. link does not exist; do nothing (set our own autogenerated AUMID)
  2. link exists, same aumid (no work required, set it on our active process)
  3. link exists, no aumid (defer write of our aumid to the link)
  4. link exists, customized/different/unexpected AUMID (#8216)

also, it is possible to determine if you were launched from a .lnk and if so which specific one; this may be broadly safer than scanning only the taskbar pins, since it will let you read the aumid from any lnk file anywhere that launches Terminal (though: it is important to note that this will also only work for links to WindowsTerminal.exe and will not work for links to wt.exe unless we do specific work to propagate that through the startup stack)

@microsoft-github-policy-service microsoft-github-policy-service Bot added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label May 1, 2026
@DHowett DHowett merged commit 059986e into main May 1, 2026
20 checks passed
@DHowett DHowett deleted the dev/cazamor/bugfix/aumid branch May 1, 2026 21:56
Qmoony pushed a commit to Qmoony/terminal that referenced this pull request May 11, 2026
The bug was caused by an AUMID mismatch between the Taskbar's .lnk file
and Windows Terminal. Since no AUMID was associated with the .exe, the
OS automatically creates one for us. However, microsoft#20018 added an AUMID for
unpackaged scenarios, so now there was a mismatch, resulting in a new
taskbar entry being created.

To fix this, we check if a .lnk points to our .exe in the taskbar.
There's 3 cases here:
1. no .lnk of interest exists --> set the AUMID normally
2. the .lnk carries our AUMID --> set the AUMID normally
3. the .lnk doesn't have an AUMID (aka uses the auto-resolved one) -->
- for this launch: don't set the AUMID so that we both use the
auto-resolved one
- on next launch: set the AUMID on the .lnk and process so that they all
agree

## Validation Steps Performed
In unpackaged folder, move WindowsTerminal.exe to the taskbar (creates
.lnk)...
✅ Double-click the .exe --> Same taskbar entry is used
✅ Double-click the .exe _again_ --> second window goes to same taskbar
entry

The first window doesn't have to close for this to work. It just * works
*!

Bug introduced in microsoft#20018 
Closes microsoft#20053
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something zBugBash-Consider

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Regression Canary] Problem start WT with lnk

4 participants